package com.easylinkin.linkappapi.powerdistribution.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.easylinkin.linkappapi.common.constant.CommonConstant;
import com.easylinkin.linkappapi.common.utils.DateUtil;
import com.easylinkin.linkappapi.common.utils.NumberUtil;
import com.easylinkin.linkappapi.device.entity.Device;
import com.easylinkin.linkappapi.device.mapper.DeviceMapper;
import com.easylinkin.linkappapi.deviceattributestatus.entity.DeviceAttributeStatus;
import com.easylinkin.linkappapi.elasticsearch.entity.SortField;
import com.easylinkin.linkappapi.elasticsearch.entity.TimeRange;
import com.easylinkin.linkappapi.elasticsearch.service.IEService;
import com.easylinkin.linkappapi.powerdistribution.entity.*;
import com.easylinkin.linkappapi.powerdistribution.mapper.DistributionCabinetRefDeviceMapper;
import com.easylinkin.linkappapi.powerdistribution.service.DistributionCabinetAlarmConfigService;
import com.easylinkin.linkappapi.powerdistribution.service.RunAnalyzeService;
import com.easylinkin.linkappapi.powerdistribution.util.ElectricityConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * class info :
 *
 * @author liuqihang
 * @date 2021/9/13 10:42
 */
@Service
@Slf4j
public class RunAnalyzeServiceImpl implements RunAnalyzeService {

    @Resource
    private DistributionCabinetRefDeviceMapper distributionCabinetRefDeviceMapper;

    @Resource
    private DeviceMapper deviceMapper;

    @Resource
    private IEService ieService;

    @Resource
    private DistributionCabinetAlarmConfigService distributionCabinetAlarmConfigService;

    @Override
    public List<Device> getDeviceListByCabinetId(String cabinetId, Integer type) {
        QueryWrapper qw = new QueryWrapper();
        qw.eq("distribution_cabinet_id", cabinetId);
        List<DistributionCabinetRefDevice> list = distributionCabinetRefDeviceMapper.selectList(qw);
        if(ObjectUtils.isEmpty(list)){
            log.info("配电柜无关联设备 cabinetId:{}", cabinetId);
            return null;
        }
        List<String> deviceCodeList = list.stream().map(DistributionCabinetRefDevice::getDeviceCode).collect(Collectors.toList());
        List<Device> deviceList = deviceMapper.getMonitorDevices(new Device().setCodes(deviceCodeList));
        if(ObjectUtils.isEmpty(deviceList)){
            log.info("配电柜无关联设备 cabinetId:{}", cabinetId);
            return null;
        }
        List<Device> deviceListResult = deviceAttributeFiler(deviceList, type);
        if(ObjectUtils.isEmpty(deviceListResult)){
            log.info("配电柜无关联设备 cabinetId:{}", cabinetId);
            return null;
        }
        return deviceListResult;
    }

    @Override
    public LoadAnalyzeResult loadAnalyze(RunAnalyzeParams runAnalyzeParams) throws IOException {
        LoadAnalyzeResult lar = new LoadAnalyzeResult();
        //上下限负荷
        Double[] upperAndLowerLimit = new Double[2];
        DistributionCabinetAlarmConfig distributionCabinetAlarmConfig = distributionCabinetAlarmConfigService.getDistributionCabinetAlarmConfigByCondition(
                new DistributionCabinetAlarmConfig().setCabinetId(runAnalyzeParams.getCabinetId()).setDeviceCode(runAnalyzeParams.getDeviceCode()).setType(1)
        );
        if(distributionCabinetAlarmConfig != null){
            upperAndLowerLimit[0] = distributionCabinetAlarmConfig.getValueMin() == null ? null : distributionCabinetAlarmConfig.getValueMin().doubleValue();
            upperAndLowerLimit[1] = distributionCabinetAlarmConfig.getValueMax() == null ? null : distributionCabinetAlarmConfig.getValueMax().doubleValue();
        }

        lar.setUpperAndLowerLimit(upperAndLowerLimit);
        //总视在功率流水数据
        List<String> necessaryFieldList = Arrays.asList(ElectricityConstant.loadAnalyzeRequiredField);
        List<ElectricityEs> esApparentPowerList = getElectricityES(runAnalyzeParams.getDate(), runAnalyzeParams.getDeviceCode(), ElectricityEs.class, necessaryFieldList);
        if(ObjectUtils.isEmpty(esApparentPowerList)){
            return null;
        }
        lar.setEsApparentPowerList(esApparentPowerList);

        OptionalDouble maxOptional = esApparentPowerList.stream().mapToDouble(ElectricityEs::getApparentPower).max();
        Double max = maxOptional.getAsDouble();
        max = NumberUtil.doubleRoundHalfUp(max, 2);
        lar.setMaxApparentPower(max);
        //日均值
        OptionalDouble averageOption = esApparentPowerList.stream().mapToDouble(ElectricityEs::getApparentPower).average();
        Double average = averageOption.getAsDouble();
        average = NumberUtil.doubleRoundHalfUp(average, 2);
        lar.setAverage(average);

        //负荷分布统计
        Map<String, LoadDistributed> intervalMap = countApparentPowerInterval(esApparentPowerList);
        lar.setIntervalMap(intervalMap);
        esApparentPowerList = null;
        return lar;
    }

    @Override
    public ElectricityParamsResult electricityParams(RunAnalyzeParams runAnalyzeParams) throws IOException {
        ElectricityParamsResult electricityParamsResult = new ElectricityParamsResult();

        //电力参数流水数据
        List<String> necessaryFieldList = Arrays.asList(ElectricityConstant.electricityParamsRequiredFieldAll);
        List<ElectricityEs> esElectricityParamList = getElectricityES(runAnalyzeParams.getDate(), runAnalyzeParams.getDeviceCode(), ElectricityEs.class, necessaryFieldList);
        if(ObjectUtils.isEmpty(esElectricityParamList)){
            return null;
        }
        electricityParamsResult.setEsApparentPowerList(esElectricityParamList);

        List<AttributeInfo> doublePhaseVoltageAttribute = calculateDoublePhaseVoltageAttribute(esElectricityParamList);
        OptionalDouble maxDoublePhaseVoltage = doublePhaseVoltageAttribute.stream().mapToDouble(AttributeInfo::getMaxValue).max();
        electricityParamsResult.setMaxDoublePhaseVoltage(maxDoublePhaseVoltage.getAsDouble());

        List<AttributeInfo> phaseVoltageAttribute = calculatePhaseVoltageAttribute(esElectricityParamList);
        OptionalDouble maxPhaseVoltage = phaseVoltageAttribute.stream().mapToDouble(AttributeInfo::getMaxValue).max();
        electricityParamsResult.setMaxPhaseVoltage(maxPhaseVoltage.getAsDouble());

        List<AttributeInfo> phaseCurrentAttribute = calculatePhaseCurrentAttribute(esElectricityParamList);
        OptionalDouble maxPhaseCurrent = phaseCurrentAttribute.stream().mapToDouble(AttributeInfo::getMaxValue).max();
        electricityParamsResult.setMaxPhaseCurrent(maxPhaseCurrent.getAsDouble());

        electricityParamsResult.setDoublePhaseVoltageAttribute(doublePhaseVoltageAttribute);
        electricityParamsResult.setPhaseVoltageAttribute(phaseVoltageAttribute);
        electricityParamsResult.setPhaseCurrentAttribute(phaseCurrentAttribute);
        esElectricityParamList = null;
        return electricityParamsResult;
    }

    @Override
    public ThreePhaseUnbalanceResult threePhaseUnbalance(RunAnalyzeParams runAnalyzeParams) throws IOException {
        ThreePhaseUnbalanceResult threePhaseUnbalanceResult = new ThreePhaseUnbalanceResult();

        //不平衡度
        Double[] unbalanceRates = new Double[2];
        DistributionCabinetAlarmConfig distributionCabinetAlarmConfig = distributionCabinetAlarmConfigService.getDistributionCabinetAlarmConfigByCondition(
                new DistributionCabinetAlarmConfig().setCabinetId(runAnalyzeParams.getCabinetId()).setDeviceCode(runAnalyzeParams.getDeviceCode()).setType(2)
        );
        if(distributionCabinetAlarmConfig != null){
            //不平衡度
            unbalanceRates[0] = distributionCabinetAlarmConfig.getValueMin() == null ? null : distributionCabinetAlarmConfig.getValueMin().doubleValue();
            //严重不平衡度
            unbalanceRates[1] = distributionCabinetAlarmConfig.getValueMax() == null ? null : distributionCabinetAlarmConfig.getValueMax().doubleValue();
        }

        threePhaseUnbalanceResult.setUnbalanceRates(unbalanceRates);

        //三相不平衡流水数据
        List<String> necessaryFieldList = Arrays.asList(ElectricityConstant.threePhaseUnBalanceField);
        List<ElectricityEs> esThreePhaseUnbalanceList = getElectricityES(runAnalyzeParams.getDate(), runAnalyzeParams.getDeviceCode(), ElectricityEs.class, necessaryFieldList);
        if(ObjectUtils.isEmpty(esThreePhaseUnbalanceList)){
            return null;
        }
        threePhaseUnbalanceResult.setEsThreePhaseUnbalanceList(esThreePhaseUnbalanceList);

        OptionalDouble maxVoltageUnbalanceRateOptional = esThreePhaseUnbalanceList.stream().mapToDouble(ElectricityEs::getVoltageUnbalanceRate).max();
        Double maxVoltageUnbalanceRate = maxVoltageUnbalanceRateOptional.getAsDouble();
        maxVoltageUnbalanceRate = NumberUtil.doubleRoundHalfUp(maxVoltageUnbalanceRate, 2);
        threePhaseUnbalanceResult.setMaxVoltageUnbalanceRate(maxVoltageUnbalanceRate);

        OptionalDouble maxCurrentUnbalanceRateOptional = esThreePhaseUnbalanceList.stream().mapToDouble(ElectricityEs::getCurrentUnbalanceRate).max();
        Double maxCurrentUnbalanceRate = maxCurrentUnbalanceRateOptional.getAsDouble();
        maxCurrentUnbalanceRate = NumberUtil.doubleRoundHalfUp(maxCurrentUnbalanceRate, 2);
        threePhaseUnbalanceResult.setMaxCurrentUnbalanceRate(maxCurrentUnbalanceRate);

        esThreePhaseUnbalanceList = null;
        return threePhaseUnbalanceResult;
    }

    @Override
    public HarmonicsResult harmonics(RunAnalyzeParams runAnalyzeParams) throws IOException {
        HarmonicsResult harmonicsResult = new HarmonicsResult();

        //谐波分析流水数据
        List<String> necessaryFieldList = Arrays.asList(ElectricityConstant.harmonicAnalyzeField);
//        List<String> necessaryFieldList = null;
        List<ElectricityEs> esHarmonicsAnalyzeList = getElectricityES(runAnalyzeParams.getDate(), runAnalyzeParams.getDeviceCode(), ElectricityEs.class, necessaryFieldList);
        if(ObjectUtils.isEmpty(esHarmonicsAnalyzeList)){
            return null;
        }

        esHarmonicsAnalyzeList = esHarmonicsAnalyzeList.stream().sorted(Comparator.comparing(ElectricityEs::getStorageTime).reversed()).collect(Collectors.toList());

        Optional<ElectricityEs> aPhaseVoltageHarmonicsEsOptional = esHarmonicsAnalyzeList.stream().max(Comparator.comparingDouble(ElectricityEs::getAPhaseVoltageHarmonics));
        Optional<ElectricityEs> bPhaseVoltageHarmonicsEsOptional = esHarmonicsAnalyzeList.stream().max(Comparator.comparingDouble(ElectricityEs::getBPhaseVoltageHarmonics));
        Optional<ElectricityEs> cPhaseVoltageHarmonicsEsOptional = esHarmonicsAnalyzeList.stream().max(Comparator.comparingDouble(ElectricityEs::getCPhaseVoltageHarmonics));

        Optional<ElectricityEs> aPhaseCurrentHarmonicsEsOptional = esHarmonicsAnalyzeList.stream().max(Comparator.comparingDouble(ElectricityEs::getAPhaseCurrentHarmonics));
        Optional<ElectricityEs> bPhaseCurrentHarmonicsEsOptional = esHarmonicsAnalyzeList.stream().max(Comparator.comparingDouble(ElectricityEs::getBPhaseCurrentHarmonics));
        Optional<ElectricityEs> cPhaseCurrentHarmonicsEsOptional = esHarmonicsAnalyzeList.stream().max(Comparator.comparingDouble(ElectricityEs::getCPhaseCurrentHarmonics));
        ElectricityEs aPhaseVoltageHarmonicsEs = aPhaseVoltageHarmonicsEsOptional.get();
        ElectricityEs bPhaseVoltageHarmonicsEs = bPhaseVoltageHarmonicsEsOptional.get();
        ElectricityEs cPhaseVoltageHarmonicsEs = cPhaseVoltageHarmonicsEsOptional.get();
        ElectricityEs vMax = getMaxHarmonicsEs(0, aPhaseVoltageHarmonicsEs, bPhaseVoltageHarmonicsEs, cPhaseVoltageHarmonicsEs);

        ElectricityEs aPhaseCurrentHarmonicsEs = aPhaseCurrentHarmonicsEsOptional.get();
        ElectricityEs bPhaseCurrentHarmonicsEs = bPhaseCurrentHarmonicsEsOptional.get();
        ElectricityEs cPhaseCurrentHarmonicsEs = cPhaseCurrentHarmonicsEsOptional.get();
        ElectricityEs cMax = getMaxHarmonicsEs(1, aPhaseCurrentHarmonicsEs, bPhaseCurrentHarmonicsEs, cPhaseCurrentHarmonicsEs);

        harmonicsResult.setMaxPhaseVoltageHarmonicsTime(formatTime(vMax.getStorageTime()));
        harmonicsResult.setPhaseVoltageHarmonics(vMax);

        harmonicsResult.setMaxPhaseCurrentHarmonicsTime(formatTime(cMax.getStorageTime()));
        harmonicsResult.setPhaseCurrentHarmonics(cMax);

        return harmonicsResult;
    }

    private String formatTime(String time){
        if(StringUtils.isEmpty(time)){
            return null;
        }
        return DateUtil.getHHMMDate(DateUtil.getDateFromFormatStr(time, DateUtil.DATE_TIME_FORMAT_DEFAULT));
    }

    private ElectricityEs getMaxHarmonicsEs(int flag, ElectricityEs aHarmonicsEs, ElectricityEs bHarmonicsEs, ElectricityEs cHarmonicsEs){
        Map<Double, List<ElectricityEs>> harmonicMap = new LinkedHashMap<>();
        if(flag == 0){
            fillHarmonicsMap(harmonicMap, aHarmonicsEs.getAPhaseVoltageHarmonics(), aHarmonicsEs);
            fillHarmonicsMap(harmonicMap, bHarmonicsEs.getBPhaseVoltageHarmonics(), bHarmonicsEs);
            fillHarmonicsMap(harmonicMap, cHarmonicsEs.getCPhaseVoltageHarmonics(), cHarmonicsEs);
        }else {
            fillHarmonicsMap(harmonicMap, aHarmonicsEs.getAPhaseCurrentHarmonics(), aHarmonicsEs);
            fillHarmonicsMap(harmonicMap, bHarmonicsEs.getBPhaseCurrentHarmonics(), bHarmonicsEs);
            fillHarmonicsMap(harmonicMap, cHarmonicsEs.getCPhaseCurrentHarmonics(), cHarmonicsEs);
        }
        Object[] key = harmonicMap.keySet().toArray();
        Arrays.sort(key, Collections.reverseOrder());
        List<ElectricityEs> electricityEs = harmonicMap.get(key[0]);
        electricityEs = electricityEs.stream().sorted(Comparator.comparing(ElectricityEs::getStorageTime).reversed()).collect(Collectors.toList());
        return electricityEs.get(0);
    }

    private Double getMax(Double ... value){
        if(value == null || value.length <= 0){
            return null;
        }
        Double max = Collections.max(Arrays.asList(value));
        return max;
    }

    private void fillHarmonicsMap(Map<Double, List<ElectricityEs>> harmonicMap, Double harmonicsValue, ElectricityEs ee){
        if(harmonicMap.containsKey(harmonicsValue)){
            List<ElectricityEs> electricityEs = harmonicMap.get(harmonicsValue);
            electricityEs.add(ee);
        }else {
            List<ElectricityEs> eeList = new ArrayList<>();
            eeList.add(ee);
            harmonicMap.put(harmonicsValue, eeList);
        }
    }


    @Override
    public List<Device> deviceAttributeFiler(List<Device> deviceList, Integer type) {
        List<String> complexTypesList = null;
        if(type.equals(CommonConstant.ONE)){
            complexTypesList = Arrays.asList(ElectricityConstant.loadAnalyzeRequiredField);
        }
        else if(type.equals(CommonConstant.TWO)){
            complexTypesList = Arrays.asList(ElectricityConstant.electricityParamsRequiredFieldAll);
        }
        else if(type.equals(CommonConstant.THREE)){
            complexTypesList = Arrays.asList(ElectricityConstant.threePhaseUnBalanceField);
        }
        else if(type.equals(CommonConstant.FOUR)){
            complexTypesList = Arrays.asList(ElectricityConstant.harmonicAnalyzeField);
        }
        else if(type.equals(CommonConstant.FIVE)){
            complexTypesList = Arrays.asList(ElectricityConstant.positiveactiveenergy);
        }else if(type.equals(CommonConstant.SIX)){
            complexTypesList = Arrays.asList(ElectricityConstant.loadIndex);
        }
        List<Device> resultList = new ArrayList<>();
        for (Device device:
                deviceList) {
            List<DeviceAttributeStatus> deviceAttributeStatusList = device.getDeviceAttributeStatusList();
            List<DeviceAttributeStatus> topAttributes = deviceAttributeStatusList.stream().filter(e -> ObjectUtils.isEmpty(e.getParentPropCode())).collect(Collectors.toList());
            for (DeviceAttributeStatus topAttribute : topAttributes) {
                if (complexTypesList.contains(topAttribute.getPropCode())) {
                    resultList.add(device);
                    break;
                }
            }
        }
        return resultList;
    }


    private Map<String, LoadDistributed> countApparentPowerInterval(List<ElectricityEs> esApparentPowerList){
        Map<String, LoadDistributed> intervalMap = new LinkedHashMap<>();
        //最大
        Double max = esApparentPowerList.stream().mapToDouble(ElectricityEs::getApparentPower).max().getAsDouble();
        //最小
        Double min = esApparentPowerList.stream().mapToDouble(ElectricityEs::getApparentPower).min().getAsDouble();

        // 区间的间隔
        Double v = (max - min) / 5;
        double step = NumberUtil.doubleRoundHalfUp(v, 2);

        double[][] intervals = new double[5][2];
        double startElement = max;
        for(int i = 0, size = 5; i < size; i++){
            intervals[i][0] = NumberUtil.doubleRoundHalfUp(startElement, 2);
            startElement = NumberUtil.doubleRoundHalfUp(startElement - step, 2);
            if(i == (size -1)){
                intervals[i][1] = NumberUtil.doubleRoundHalfUp(min, 2);
            }else {
                intervals[i][1] = NumberUtil.doubleRoundHalfUp(startElement, 2);
            }
        }
        log.info("intervals=" + JSON.toJSONString(intervals));
        for(int j = 0, size2 = 5; j < size2; j++){
            List<ElectricityEs> eeList = null;
            if(j == (size2 -1)){
                eeList = funStream(esApparentPowerList, intervals[j], true);
            }else {
                eeList = funStream(esApparentPowerList, intervals[j], false);
            }

            Double result = Double.valueOf(eeList.size())/Double.valueOf(esApparentPowerList.size());
            Double percentage = new BigDecimal(result).multiply(BigDecimal.valueOf(100L)).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            intervalMap.put(intervals[j][1] + "~" + intervals[j][0], new LoadDistributed().setPercentage(percentage).setNum(eeList.size()));
        }
        log.info("intervalMap=" + JSON.toJSONString(intervalMap));
        return intervalMap;
    }

    private static List<ElectricityEs> funStream(List<ElectricityEs> list, double[] childInterval, boolean endFlag) {
        List<ElectricityEs> collect = null;
        if(endFlag){
            collect = list.stream().filter(e -> (e.getApparentPower() <= childInterval[0] && e.getApparentPower() >= childInterval[1])).collect(Collectors.toList());
        }else {
            collect = list.stream().filter(e -> (e.getApparentPower() <= childInterval[0] && e.getApparentPower() > childInterval[1])).collect(Collectors.toList());
        }
        return collect;
    }

    private <T> List<T> getElectricityES(String date, String deviceCode, Class<T> clazz, List<String> necessaryFieldList) throws IOException {
        Map<String, Object> likeQueryMap = new HashMap<>(16);
        likeQueryMap.put("deviceCodeTerm", deviceCode);
        TimeRange timeRange = new TimeRange();
        String[] dates = DateUtil.fillDateHHMMSS(date);
        timeRange.setStartTime(dates[0]).setEndTime(dates[1]).setFieldName("storageTime");
        SortField sortField = new SortField().setFieldName("storageTime").setSortOrder(SortOrder.ASC);

        String indices = ieService.getIndicesListByDate(dates[0], dates[1]);

        SearchResponse searchResponse = ieService.getDeviceFlowListFromES(likeQueryMap, 1, 10000, timeRange, necessaryFieldList,
                sortField, null, indices);
        //游标查询返回ID
        String scrollId = null;
        List<T> electricityEsList = new ArrayList<>();
        if (Objects.nonNull(searchResponse) && Objects.equals(searchResponse.status(), RestStatus.OK)) {

            SearchHit[] hits = searchResponse.getHits().getHits();
            if(hits != null && hits.length > 0){
                for (SearchHit hit : hits) {
                    T electricityEs = parseObject(hit.getSourceAsString(), clazz);
                    electricityEsList.add(electricityEs);
                }
                scrollId = searchResponse.getScrollId();
            }
        }
        log.info("scrollId=" + scrollId);
        while(true){
            if(scrollId == null){
                break;
            }
            SearchResponse scrollResponse = ieService.getScrollData(scrollId);
            if (Objects.nonNull(scrollResponse) && Objects.equals(scrollResponse.status(), RestStatus.OK)) {
                SearchHit[] scrollHits = scrollResponse.getHits().getHits();
                if(scrollHits != null && scrollHits.length > 0){
                    log.info("scrollHits length=" + scrollHits.length);
                    for (SearchHit scrollHit : scrollHits) {
                        T electricityEs = parseObject(scrollHit.getSourceAsString(), clazz);
                        electricityEsList.add(electricityEs);
                    }
                    scrollId = scrollResponse.getScrollId();
                }
                else {
                    break;
                }
            }
            else {
                break;
            }
        }
        return electricityEsList;
    }

    private <T> T parseObject(String json, Class<T> clazz){
        T result = JSONObject.parseObject(json, clazz);
        return result;
    }


    private List<AttributeInfo> calculateDoublePhaseVoltageAttribute(List<ElectricityEs> esElectricityParamList){
        List<AttributeInfo> doublePhaseVoltageAttribute = new ArrayList<>();
        AttributeInfo abAttributeInfo = new AttributeInfo();
        Optional<ElectricityEs> abMaxElectricityEsOptional = esElectricityParamList.stream().max(Comparator.comparingDouble(ElectricityEs::getAbPhaseVoltage));
        Optional<ElectricityEs> abMinElectricityEsOptional = esElectricityParamList.stream().min(Comparator.comparingDouble(ElectricityEs::getAbPhaseVoltage));
        OptionalDouble abAverageOptional = esElectricityParamList.stream().mapToDouble(ElectricityEs::getAbPhaseVoltage).average();
        Double abAverage = abAverageOptional.getAsDouble();
        abAverage = NumberUtil.doubleRoundHalfUp(abAverage, 2);
        ElectricityEs abMaxElectricityEs = abMaxElectricityEsOptional.get();
        ElectricityEs abMinElectricityEs = abMinElectricityEsOptional.get();
        abAttributeInfo.setMaxValue(abMaxElectricityEs.getAbPhaseVoltage())
                .setMaxTime(DateUtil.getDateFromFormatStr(abMaxElectricityEs.getStorageTime(), DateUtil.DATE_TIME_FORMAT_DEFAULT))
                .setMinValue(abMinElectricityEs.getAbPhaseVoltage())
                .setMinTime(DateUtil.getDateFromFormatStr(abMinElectricityEs.getStorageTime(), DateUtil.DATE_TIME_FORMAT_DEFAULT))
                .setAvgValue(abAverage).setDescribe("AB线电压");


        AttributeInfo bcAttributeInfo = new AttributeInfo();
        Optional<ElectricityEs> bcMaxElectricityEsOptional = esElectricityParamList.stream().max(Comparator.comparingDouble(ElectricityEs::getBcPhaseVoltage));
        Optional<ElectricityEs> bcMinElectricityEsOptional = esElectricityParamList.stream().min(Comparator.comparingDouble(ElectricityEs::getBcPhaseVoltage));
        OptionalDouble bcAverageOptional = esElectricityParamList.stream().mapToDouble(ElectricityEs::getBcPhaseVoltage).average();
        Double bcAverage = bcAverageOptional.getAsDouble();
        bcAverage = NumberUtil.doubleRoundHalfUp(bcAverage, 2);
        ElectricityEs bcMaxElectricityEs = bcMaxElectricityEsOptional.get();
        ElectricityEs bcMinElectricityEs = bcMinElectricityEsOptional.get();
        bcAttributeInfo.setMaxValue(bcMaxElectricityEs.getBcPhaseVoltage())
                .setMaxTime(DateUtil.getDateFromFormatStr(bcMaxElectricityEs.getStorageTime(), DateUtil.DATE_TIME_FORMAT_DEFAULT))
                .setMinValue(bcMinElectricityEs.getBcPhaseVoltage())
                .setMinTime(DateUtil.getDateFromFormatStr(bcMinElectricityEs.getStorageTime(), DateUtil.DATE_TIME_FORMAT_DEFAULT))
                .setAvgValue(bcAverage).setDescribe("BC线电压");

        AttributeInfo acAttributeInfo = new AttributeInfo();
        Optional<ElectricityEs> acMaxElectricityEsOptional = esElectricityParamList.stream().max(Comparator.comparingDouble(ElectricityEs::getAcPhaseVoltage));
        Optional<ElectricityEs> acMinElectricityEsOptional = esElectricityParamList.stream().min(Comparator.comparingDouble(ElectricityEs::getAcPhaseVoltage));
        OptionalDouble acAverageOptional = esElectricityParamList.stream().mapToDouble(ElectricityEs::getAcPhaseVoltage).average();
        Double acAverage = acAverageOptional.getAsDouble();
        acAverage = NumberUtil.doubleRoundHalfUp(acAverage, 2);
        ElectricityEs acMaxElectricityEs = acMaxElectricityEsOptional.get();
        ElectricityEs acMinElectricityEs = acMinElectricityEsOptional.get();
        acAttributeInfo.setMaxValue(acMaxElectricityEs.getAcPhaseVoltage())
                .setMaxTime(DateUtil.getDateFromFormatStr(acMaxElectricityEs.getStorageTime(), DateUtil.DATE_TIME_FORMAT_DEFAULT))
                .setMinValue(acMinElectricityEs.getAcPhaseVoltage())
                .setMinTime(DateUtil.getDateFromFormatStr(acMinElectricityEs.getStorageTime(), DateUtil.DATE_TIME_FORMAT_DEFAULT))
                .setAvgValue(acAverage).setDescribe("CA线电压");

        doublePhaseVoltageAttribute.add(abAttributeInfo);
        doublePhaseVoltageAttribute.add(bcAttributeInfo);
        doublePhaseVoltageAttribute.add(acAttributeInfo);
        return doublePhaseVoltageAttribute;
    }

    private List<AttributeInfo> calculatePhaseVoltageAttribute(List<ElectricityEs> esElectricityParamList){
        List<AttributeInfo> phaseVoltageAttribute = new ArrayList<>();
        AttributeInfo aAttributeInfo = new AttributeInfo();
        Optional<ElectricityEs> aMaxElectricityEsOptional = esElectricityParamList.stream().max(Comparator.comparingDouble(ElectricityEs::getAPhaseVoltage));
        Optional<ElectricityEs> aMinElectricityEsOptional = esElectricityParamList.stream().min(Comparator.comparingDouble(ElectricityEs::getAPhaseVoltage));
        OptionalDouble aAverageOptional = esElectricityParamList.stream().mapToDouble(ElectricityEs::getAPhaseVoltage).average();
        Double aAverage = aAverageOptional.getAsDouble();
        aAverage = NumberUtil.doubleRoundHalfUp(aAverage, 2);
        ElectricityEs aMaxElectricityEs = aMaxElectricityEsOptional.get();
        ElectricityEs aMinElectricityEs = aMinElectricityEsOptional.get();
        aAttributeInfo.setMaxValue(aMaxElectricityEs.getAPhaseVoltage())
                .setMaxTime(DateUtil.getDateFromFormatStr(aMaxElectricityEs.getStorageTime(), DateUtil.DATE_TIME_FORMAT_DEFAULT))
                .setMinValue(aMinElectricityEs.getAPhaseVoltage())
                .setMinTime(DateUtil.getDateFromFormatStr(aMinElectricityEs.getStorageTime(), DateUtil.DATE_TIME_FORMAT_DEFAULT))
                .setAvgValue(aAverage).setDescribe("A相电压");


        AttributeInfo bAttributeInfo = new AttributeInfo();
        Optional<ElectricityEs> bMaxElectricityEsOptional = esElectricityParamList.stream().max(Comparator.comparingDouble(ElectricityEs::getBPhaseVoltage));
        Optional<ElectricityEs> bMinElectricityEsOptional = esElectricityParamList.stream().min(Comparator.comparingDouble(ElectricityEs::getBPhaseVoltage));
        OptionalDouble bAverageOptional = esElectricityParamList.stream().mapToDouble(ElectricityEs::getBPhaseVoltage).average();
        Double bAverage = bAverageOptional.getAsDouble();
        bAverage = NumberUtil.doubleRoundHalfUp(bAverage, 2);
        ElectricityEs bMaxElectricityEs = bMaxElectricityEsOptional.get();
        ElectricityEs bMinElectricityEs = bMinElectricityEsOptional.get();
        bAttributeInfo.setMaxValue(bMaxElectricityEs.getBPhaseVoltage())
                .setMaxTime(DateUtil.getDateFromFormatStr(bMaxElectricityEs.getStorageTime(), DateUtil.DATE_TIME_FORMAT_DEFAULT))
                .setMinValue(bMinElectricityEs.getBPhaseVoltage())
                .setMinTime(DateUtil.getDateFromFormatStr(bMinElectricityEs.getStorageTime(), DateUtil.DATE_TIME_FORMAT_DEFAULT))
                .setAvgValue(bAverage).setDescribe("B相电压");

        AttributeInfo cAttributeInfo = new AttributeInfo();
        Optional<ElectricityEs> cMaxElectricityEsOptional = esElectricityParamList.stream().max(Comparator.comparingDouble(ElectricityEs::getCPhaseVoltage));
        Optional<ElectricityEs> cMinElectricityEsOptional = esElectricityParamList.stream().min(Comparator.comparingDouble(ElectricityEs::getCPhaseVoltage));
        OptionalDouble cAverageOptional = esElectricityParamList.stream().mapToDouble(ElectricityEs::getCPhaseVoltage).average();
        Double cAverage = cAverageOptional.getAsDouble();
        cAverage = NumberUtil.doubleRoundHalfUp(cAverage, 2);
        ElectricityEs cMaxElectricityEs = cMaxElectricityEsOptional.get();
        ElectricityEs cMinElectricityEs = cMinElectricityEsOptional.get();
        cAttributeInfo.setMaxValue(cMaxElectricityEs.getCPhaseVoltage())
                .setMaxTime(DateUtil.getDateFromFormatStr(cMaxElectricityEs.getStorageTime(), DateUtil.DATE_TIME_FORMAT_DEFAULT))
                .setMinValue(cMinElectricityEs.getCPhaseVoltage())
                .setMinTime(DateUtil.getDateFromFormatStr(cMinElectricityEs.getStorageTime(), DateUtil.DATE_TIME_FORMAT_DEFAULT))
                .setAvgValue(cAverage).setDescribe("C相电压");

        phaseVoltageAttribute.add(aAttributeInfo);
        phaseVoltageAttribute.add(bAttributeInfo);
        phaseVoltageAttribute.add(cAttributeInfo);
        return phaseVoltageAttribute;
    }

    private List<AttributeInfo> calculatePhaseCurrentAttribute(List<ElectricityEs> esElectricityParamList){
        List<AttributeInfo> phaseCurrentAttribute = new ArrayList<>();
        AttributeInfo aAttributeInfo = new AttributeInfo();
        Optional<ElectricityEs> aMaxElectricityEsOptional = esElectricityParamList.stream().max(Comparator.comparingDouble(ElectricityEs::getAPhaseCurrent));
        Optional<ElectricityEs> aMinElectricityEsOptional = esElectricityParamList.stream().min(Comparator.comparingDouble(ElectricityEs::getAPhaseCurrent));
        OptionalDouble aAverageOptional = esElectricityParamList.stream().mapToDouble(ElectricityEs::getAPhaseCurrent).average();
        Double aAverage = aAverageOptional.getAsDouble();
        aAverage = NumberUtil.doubleRoundHalfUp(aAverage, 2);
        ElectricityEs aMaxElectricityEs = aMaxElectricityEsOptional.get();
        ElectricityEs aMinElectricityEs = aMinElectricityEsOptional.get();
        aAttributeInfo.setMaxValue(aMaxElectricityEs.getAPhaseCurrent())
                .setMaxTime(DateUtil.getDateFromFormatStr(aMaxElectricityEs.getStorageTime(), DateUtil.DATE_TIME_FORMAT_DEFAULT))
                .setMinValue(aMinElectricityEs.getAPhaseCurrent())
                .setMinTime(DateUtil.getDateFromFormatStr(aMinElectricityEs.getStorageTime(), DateUtil.DATE_TIME_FORMAT_DEFAULT))
                .setAvgValue(aAverage).setDescribe("A相电流");


        AttributeInfo bAttributeInfo = new AttributeInfo();
        Optional<ElectricityEs> bMaxElectricityEsOptional = esElectricityParamList.stream().max(Comparator.comparingDouble(ElectricityEs::getBPhaseCurrent));
        Optional<ElectricityEs> bMinElectricityEsOptional = esElectricityParamList.stream().min(Comparator.comparingDouble(ElectricityEs::getBPhaseCurrent));
        OptionalDouble bAverageOptional = esElectricityParamList.stream().mapToDouble(ElectricityEs::getBPhaseCurrent).average();
        Double bAverage = bAverageOptional.getAsDouble();
        bAverage = NumberUtil.doubleRoundHalfUp(bAverage, 2);
        ElectricityEs bMaxElectricityEs = bMaxElectricityEsOptional.get();
        ElectricityEs bMinElectricityEs = bMinElectricityEsOptional.get();
        bAttributeInfo.setMaxValue(bMaxElectricityEs.getBPhaseCurrent())
                .setMaxTime(DateUtil.getDateFromFormatStr(bMaxElectricityEs.getStorageTime(), DateUtil.DATE_TIME_FORMAT_DEFAULT))
                .setMinValue(bMinElectricityEs.getBPhaseCurrent())
                .setMinTime(DateUtil.getDateFromFormatStr(bMinElectricityEs.getStorageTime(), DateUtil.DATE_TIME_FORMAT_DEFAULT))
                .setAvgValue(bAverage).setDescribe("B相电流");

        AttributeInfo cAttributeInfo = new AttributeInfo();
        Optional<ElectricityEs> cMaxElectricityEsOptional = esElectricityParamList.stream().max(Comparator.comparingDouble(ElectricityEs::getCPhaseCurrent));
        Optional<ElectricityEs> cMinElectricityEsOptional = esElectricityParamList.stream().min(Comparator.comparingDouble(ElectricityEs::getCPhaseCurrent));
        OptionalDouble cAverageOptional = esElectricityParamList.stream().mapToDouble(ElectricityEs::getCPhaseCurrent).average();
        Double cAverage = cAverageOptional.getAsDouble();
        cAverage = NumberUtil.doubleRoundHalfUp(cAverage, 2);
        ElectricityEs cMaxElectricityEs = cMaxElectricityEsOptional.get();
        ElectricityEs cMinElectricityEs = cMinElectricityEsOptional.get();
        cAttributeInfo.setMaxValue(cMaxElectricityEs.getCPhaseCurrent())
                .setMaxTime(DateUtil.getDateFromFormatStr(cMaxElectricityEs.getStorageTime(), DateUtil.DATE_TIME_FORMAT_DEFAULT))
                .setMinValue(cMinElectricityEs.getCPhaseCurrent())
                .setMinTime(DateUtil.getDateFromFormatStr(cMinElectricityEs.getStorageTime(), DateUtil.DATE_TIME_FORMAT_DEFAULT))
                .setAvgValue(cAverage).setDescribe("C相电流");

        phaseCurrentAttribute.add(aAttributeInfo);
        phaseCurrentAttribute.add(bAttributeInfo);
        phaseCurrentAttribute.add(cAttributeInfo);
        return phaseCurrentAttribute;
    }




}
